package com.cskaoyan.wordmemorize.sms;

import com.cskaoyan.wordmemorize.dao.entity.UserRemindMessageDO;
import com.cskaoyan.wordmemorize.dao.mapper.UserRemindMessageMapper;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.concurrent.DelayQueue;

@Component
@Slf4j
public class SmsConsumer {

    // 延迟队列
    @Resource
    DelayQueue<SmsDelayMessage> delayQueue;

    // 消息发送工具类对象
    @Resource
    SmsSender smsSender;

    // mapper用来在发送短信后，插入发送短信的记录
    @Resource
    UserRemindMessageMapper userRemindMessageMapper;


    /**
     这里@PstConstruct注解的作用为，让Spring在创建完对象后，自动调用该方法
     来完成对象的初始化(也就是说该方法会被Spring自动调用)
     */
    @PostConstruct
    public void init() {
        log.info("start to consume message...");

        // 启动线程(也可以自己查阅资料使用其他方式启动线程)
        new Thread(() -> {
            while (true) {
                try {
                    // 获取延迟队列中的短信消息对象(注意如果没有或者队头元素延迟时间未到会在这里阻塞)
                    SmsDelayMessage message = delayQueue.take();

                    // 获取到短信消息后，发送
                    smsSender.sendRemindMessage(message.getUserName(), message.getVocCount(), message.getPhoneNumber());

                    // 在数据库添加消息发送记录
                    UserRemindMessageDO remindMessage = new UserRemindMessageDO();
                    remindMessage.setUserId(message.getUserId());
                    remindMessage.setPhoneNumber(message.getPhoneNumber());
                    userRemindMessageMapper.insert(remindMessage);
                    log.info("Inserted reminder message record for user: {}", message.getUserId());
                }catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    log.error("Thread interrupted while waiting for messages in delay queue", e);
                } catch (Exception e) {
                    log.error("Error sending reminder SMS or inserting record", e);
                }
            }
        }).start();
    }

}
